
;; =============================================================================
;; produces form that tests whether a given list matches arglist
(defun bindings-matches-p (arglist srclist)
  (check-type arglist list) ; arglist might be nil or cons
  (check-type srclist symbol) ; srclist shall always be a symbol
  (let (result
	has-rest prev-rest
	(pos 0))
    
   ))

;; =============================================================================
;; creates variable's binding list
(defun create-bindings-list (arglist srclist)
  (check-type arglist list) ; arglist might be nil or cons
  (check-type srclist symbol) ; srclist shall always be a symbol
  (let (result has-rest prev-rest (pos 0))
    (dolist (arg arglist)
      ;; only symbols are supported
      (check-type arg symbol)
      ;; mapping selector
      (cond
	;; &rest handler
	((eq arg '&rest)
	 (if has-rest (error "rest was defined"))
	 (setf has-rest t)
	 (setf prev-rest t))
	;; &optional handler
	((eq arg '&optional)
	 (error "not implemented"))
	;; ordinary symbol - direct argument mapping introduced here
	;; arguments shall look as follows: ({arg-name} ({extractor-function} srclist))
	(t (setf result
		 (append result
			 (list
			  (list arg
				;; append extractor function
				(if prev-rest
				    ;; prev token is rest
				    (progn
				      (setf prev-rest nil)
				      (cond
					((eq pos 0) srclist) ; binding to list itself
					((eq pos 1) (list 'cdr srclist)) ; good old cdr
					(t (list 'nthcdr pos srclist)) ; nthcdr otherwise
					))
				    ;; no prev token, ordinary argument is given
				    (progn
				      (if has-rest
					  (error "illegal argument: &rest defined for prev arg"))
				      (if (zerop pos)
					  (list 'car srclist)
					  (list 'nth pos srclist))))))))
	   ;; advance to new position
	   (incf pos))))
    result))

;; =============================================================================
;; produces static bindings to the given list according to the
;; arglist given
(defmacro static-bindings (srclist arglist &rest form)
  `(let (,@(create-bindings-list arglist srclist))
    ,@form))


;; =============================================================================
;; provides macro expansion
(defmacro gen-cond-expansion (func-id func-body &rest mapping-list)
  `(cond
    ,@(loop for i in mapping-list collect
	    `((eq ',(car i) ,func-id)
	      (static-bindings ,func-body ,(cadr i) ,@(cddr i))))
    (t (error "unexpected func-id"))
    ))
